package com.tlgen.orm.utils.orm;

import com.google.common.collect.Lists;
import com.tlgen.orm.annotation.AsNotField;
import com.tlgen.orm.components.cache.CacheKeyGenerator;
import com.tlgen.orm.components.cache.CacheManager;
import com.tlgen.orm.components.cache.CaffeineCacheManager;
import com.tlgen.orm.components.cache.ConcurrentCacheManager;
import com.tlgen.orm.components.offHeap.OffHeapManager;
import com.tlgen.orm.config.SpeedOrmConfig;
import com.tlgen.orm.model.Model;
import com.tlgen.orm.model.PageResult;
import com.tlgen.orm.param.QueryParams;
import com.tlgen.orm.support.ModelExecutor;
import com.tlgen.orm.support.QueryOperator;
import com.tlgen.orm.utils.reflect.ReflectionUtils;
import com.tlgen.orm.utils.SpringUtils;
import com.tlgen.orm.utils.log.TraceLog;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.BinaryOperator;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import static com.tlgen.orm.constant.SQLScript.*;
import static com.tlgen.orm.support.QueryFactory.mappingOperator;
import static com.tlgen.orm.utils.StringUtils.uncapUnderline;
import static com.tlgen.orm.utils.orm.CursorUtils.getCursorField;
import static com.tlgen.orm.utils.orm.ORMUtils.*;

@Slf4j
public class SQLGenUtils {

    public static <T> List<T> select(Class<T> tClass) {
        String SQL = SELECT_PREFIX
                .concat(getTableName(tClass))
                .concat(SEPARATOR_SPACE);
        TraceLog.out(SQL);
        return queryCacheable(SQL, (Class<List<T>>) tClass, () -> ModelExecutor.selectResult(SQL, tClass));
    }

    public static <T> List<T> select(QueryOperator<T> queryOperator, Class<T> tClass) {
        String SQL = SELECT_PREFIX
                .concat(getTableName(tClass))
                .concat(SEPARATOR_SPACE)
                .concat(mappingOperator(ORMUtils.getQueryParamsList(queryOperator, tClass)));
        SQL = SQL.replaceFirst("AND", "WHERE")
                .replace("WHERE  GROUP BY", "GROUP BY")
                .replace("WHERE  ORDER BY", "ORDER BY")
                .replace("AND  ORDER BY", "ORDER BY");
        TraceLog.out(SQL);
        String finalSQL = SQL;
        return queryCacheable(SQL, (Class<List<T>>) tClass, () -> ModelExecutor.selectResult(finalSQL, tClass));
    }

    public static <T> T selectOne(QueryOperator<T> queryOperator, Class<T> tClass) {
        String SQL = SELECT_PREFIX
                .concat(getTableName(tClass))
                .concat(SEPARATOR_SPACE)
                .concat(mappingOperator(ORMUtils.getQueryParamsList(queryOperator, tClass)));
        SQL = SQL.replaceFirst("AND", "WHERE")
                .replace("WHERE  GROUP BY", "GROUP BY")
                .replace("WHERE  ORDER BY", "ORDER BY")
                .replace("AND  ORDER BY", "ORDER BY")
                .concat(SEPARATOR_SPACE)
                .concat("LIMIT 1");
        TraceLog.out(SQL);
        String finalSQL = SQL;
        return queryCacheable(SQL, tClass, () -> ModelExecutor.selectSingleResult(finalSQL, tClass));
    }

    public static <T> T selectOne(QueryOperator<T> queryOperator, QueryOperator<T> queryOperatorDefinition, Class<T> tClass) {
        // 添加自定义复杂条件查询
        if (CollectionUtils.isNotEmpty(queryOperatorDefinition.getParamsList())) {
            for (QueryParams queryParams : queryOperatorDefinition.getParamsList()) {
                queryOperator.getParamsList().add(queryParams);
            }
        }
        String SQL = SELECT_PREFIX
                .concat(getTableName(tClass))
                .concat(SEPARATOR_SPACE)
                .concat(mappingOperator(ORMUtils.getQueryParamsList(queryOperator, tClass)));
        SQL = SQL.replaceFirst("AND", "WHERE")
                .replace("WHERE  GROUP BY", "GROUP BY")
                .replace("WHERE  ORDER BY", "ORDER BY")
                .replace("AND  ORDER BY", "ORDER BY")
                .concat(SEPARATOR_SPACE)
                .concat("LIMIT 1");
        TraceLog.out(SQL);
        String finalSQL = SQL;
        return queryCacheable(SQL, tClass, () -> ModelExecutor.selectSingleResult(finalSQL, tClass));
    }

    public static <T> Object save(Object o) {
        Class<?> aClass = o.getClass();
        String primaryKey = ORMUtils.getPrimaryKey(aClass);
        Object id = null;
        List<String> columns = Lists.newArrayList();
        List<Object> values = Lists.newArrayList();

        // 递归收集所有层级的字段
        List<Field> allFields = getAllFields(aClass);

        // 获取ID的实际类型(考虑泛型)
        Class<?> idType = resolveActualIdType(o);
        Object nextId = shouldGenerateId(o, primaryKey) ? generateIdByType(idType) : null;

        for (Field field : allFields) {
            field.setAccessible(true);

            // 跳过不映射字段
            if (field.isAnnotationPresent(AsNotField.class)) continue;

            String fieldName = field.getName();
            Object fieldValue = getProcessedFieldValue(o, field, primaryKey, nextId);

            // 处理主键ID记录
            if (fieldName.equals(primaryKey) && fieldValue != null) {
                id = fieldValue;
            }

            columns.add(uncapUnderline(fieldName));
            values.add(fieldValue);
        }

        // 构建并执行SQL
        String valuesPart = formatValues(values);
        String SQL = buildInsertSQL(aClass, columns, valuesPart);
        TraceLog.out(SQL);
        ModelExecutor.execute(o, SQL);

        // 缓存一致性管理
        if (Holder.SPEED_ORM_CONFIG_INSTANCE.getOpenCache()) {
            try {
                String tableName = getTableName(aClass);
                // 清理Map缓存
                cacheManager.evictByTable(tableName);

                // 清理该类型的所有缓存
                OffHeapManager.removeByEntityType(aClass);

            } catch (Exception e) {
                log.error("Failed to clear cache", e);
            }
        }

        return id;
    }

    public static <T> void update(QueryOperator<T> queryOperator, Object o) {
        List<QueryParams> paramsList = ORMUtils.getQueryParamsList(queryOperator, o.getClass());
        // 获取查询条件
        String mappingOperator = mappingOperator(paramsList);
        Class<?> aClass = o.getClass();
        String primaryKeyName = ORMUtils.getPrimaryKey(aClass);
        // 收集属性名
        List<String> columns = Lists.newArrayList();
        // 收集属性对应的值
        List<Object> values = Lists.newArrayList();
        List<Field> allFields = getAllFields(aClass);
        for (Field field : allFields) {
            String fieldName = field.getName();
            Object fieldValue = ReflectionUtils.getFieldValue(o, field.getName());
            if (!Objects.equals(primaryKeyName, fieldName)) {
                values.add(fieldValue);
                columns.add(uncapUnderline(fieldName));
            }
        }
        // 处理值
        StringBuilder stringBuffer = new StringBuilder();
        for (
                int i = 0; i < columns.size() && values.get(i) != null; i++) {
            stringBuffer.append(columns.get(i)
                    .concat(SEPARATOR_EQUAL)
                    .concat(SEPARATOR_SINGLE_QUOTA)
                    .concat(String.valueOf(values.get(i)))
                    .concat(SEPARATOR_SINGLE_QUOTA)
                    .concat(SEPARATOR_COMMA)
            );
        }

        String bufferString = stringBuffer.toString();
        if (!bufferString.isEmpty()) {
            bufferString = bufferString.substring(0, stringBuffer.length() - 2);
        }

        // 组装 SQL
        String SQL = UPDATE_PREFIX
                .concat(getTableName(aClass))
                .concat(UPDATE_SET)
                .concat(bufferString)
                .concat(mappingOperator);
        SQL = SQL.replaceFirst("AND", "WHERE");
        TraceLog.out(SQL);
        ModelExecutor.execute(SQL);

        if (Holder.SPEED_ORM_CONFIG_INSTANCE.getOpenCache()) {
            // 清除相关缓存
            try {
                String tableName = getTableName(aClass);
                cacheManager.evictByTable(tableName);

                // 清理该类型的所有缓存
                OffHeapManager.removeByEntityType(aClass);

            } catch (Exception e) {
                log.error("Failed to clear cache", e);
            }
        }

    }

    public static <T> void updateSelective(QueryOperator<T> queryOperator, Object o) {
        List<QueryParams> paramsList = ORMUtils.getQueryParamsList(queryOperator, o.getClass());
        // 获取查询条件
        String mappingOperator = mappingOperator(paramsList);
        Class<?> aClass = o.getClass();
        String primaryKeyName = ORMUtils.getPrimaryKey(aClass);
        // 收集属性名
        List<String> columns = Lists.newArrayList();
        // 收集属性对应的值
        List<Object> values = Lists.newArrayList();
        List<Field> allFields = getAllFields(aClass);
        for (Field field : allFields) {
            String fieldName = field.getName();
            Object fieldValue = ReflectionUtils.getFieldValue(o, field.getName());
            if (!Objects.equals(primaryKeyName, fieldName)) {
                values.add(fieldValue);
                columns.add(uncapUnderline(fieldName));
            }
        }
        // 1.主键 id 不参与 set 语句
        // 2.如果值为空的属性不参与 set 语句
        // 3.作为条件的属性不参与 set 语句
        List<String> queryColumns = paramsList.stream().map(QueryParams::getColumn).collect(Collectors.toList());
        for (int i = values.size() - 1; i < values.size(); i--) {
            if (Objects.equals(columns.get(i), primaryKeyName)) {
                values.remove(i);
                columns.remove(i);
            }
            if (Objects.isNull(values.get(i))) {
                values.remove(i);
                columns.remove(i);
            }
            if (queryColumns.contains(columns.get(i))) {
                values.remove(i);
                columns.remove(i);
            }
        }
        // 处理值
        StringBuilder stringBuffer = new StringBuilder();
        for (int i = 0; i < columns.size() && values.get(i) != null; i++) {
            stringBuffer.append(columns.get(i)
                    .concat(SEPARATOR_EQUAL)
                    .concat(SEPARATOR_SINGLE_QUOTA)
                    .concat(String.valueOf(values.get(i)))
                    .concat(SEPARATOR_SINGLE_QUOTA)
                    .concat(SEPARATOR_COMMA)
            );
        }
        String bufferString = stringBuffer.toString();
        if (!bufferString.isEmpty()) {
            bufferString = bufferString.substring(0, stringBuffer.length() - 2);
        }
        // 组装 SQL
        String SQL = UPDATE_PREFIX
                .concat(getTableName(aClass))
                .concat(UPDATE_SET)
                .concat(bufferString)
                .concat(mappingOperator);
        SQL = SQL.replaceFirst("AND", "WHERE");
        TraceLog.out(SQL);
        ModelExecutor.execute(SQL);

        if (Holder.SPEED_ORM_CONFIG_INSTANCE.getOpenCache()) {
            // 清除相关缓存
            try {
                String tableName = getTableName(aClass);
                cacheManager.evictByTable(tableName);

                // 清理该类型的所有缓存
                OffHeapManager.removeByEntityType(aClass);

            } catch (Exception e) {
                log.error("Failed to clear cache", e);
            }
        }

    }

    public static <T> void update(Object o) {
        Class<?> aClass = o.getClass();
        String primaryKeyName = ORMUtils.getPrimaryKey(aClass);
        Object id = null;
        // 收集属性名
        List<String> columns = Lists.newArrayList();
        // 收集属性对应的值
        List<Object> values = Lists.newArrayList();
        List<Field> allFields = getAllFields(aClass);
        for (Field field : allFields) {
            String fieldName = field.getName();
            Object fieldValue = ReflectionUtils.getFieldValue(o, field.getName());
            if (Objects.equals(primaryKeyName, fieldName)) {
                id = fieldValue;
            } else {
                values.add(fieldValue);
                columns.add(uncapUnderline(fieldName));
            }
        }
        // 处理值
        StringBuilder stringBuffer = new StringBuilder();
        for (int i = 0; i < columns.size(); i++) {
            stringBuffer.append(columns.get(i)
                    .concat(SEPARATOR_EQUAL)
                    .concat(SEPARATOR_SINGLE_QUOTA)
                    .concat(Objects.nonNull(values.get(i)) ? String.valueOf(values.get(i)) : "null")
                    .concat(SEPARATOR_SINGLE_QUOTA)
                    .concat(SEPARATOR_COMMA)
            );
        }
        String bufferString = stringBuffer.toString();
        if (!bufferString.isEmpty()) {
            bufferString = bufferString.substring(0, stringBuffer.length() - 2);
        }
        // 组装 SQL
        String SQL = UPDATE_PREFIX
                .concat(getTableName(aClass))
                .concat(UPDATE_SET)
                .concat(bufferString)
                .concat(SEPARATOR_WHERE)
                .concat(primaryKeyName)
                .concat(SEPARATOR_EQUAL)
                .concat(SEPARATOR_SINGLE_QUOTA)
                .concat(String.valueOf(id))
                .concat(SEPARATOR_SINGLE_QUOTA);
        SQL = SQL.replaceAll("'null'", "null");
        TraceLog.out(SQL);
        ModelExecutor.execute(SQL);

        if (Holder.SPEED_ORM_CONFIG_INSTANCE.getOpenCache()) {
            // 清除相关缓存
            try {
                if (id != null) {
                    String tableName = getTableName(aClass);
                    cacheManager.evictById(tableName, id);

                    // 清理该类型的所有缓存
                    OffHeapManager.removeByEntityType(aClass);

                }
            } catch (Exception e) {
                log.error("Failed to clear cache", e);
            }
        }

    }

    public static <T> void updateSelective(Object o) {
        Class<?> aClass = o.getClass();
        String primaryKeyName = ORMUtils.getPrimaryKey(aClass);
        Object id = null;
        // 收集属性名
        List<String> columns = Lists.newArrayList();
        // 收集属性对应的值
        List<Object> values = Lists.newArrayList();
        List<Field> allFields = getAllFields(aClass);
        for (Field field : allFields) {
            String fieldName = field.getName();
            Object fieldValue = ReflectionUtils.getFieldValue(o, field.getName());
            if (Objects.equals(primaryKeyName, fieldName)) {
                id = fieldValue;
            } else {
                values.add(fieldValue);
                columns.add(uncapUnderline(fieldName));
            }
        }
        // 1.主键 id 不参与 set 语句
        // 2.如果值为空的属性不参与 set 语句
        for (int i = values.size() - 1; i < values.size(); i--) {
            if (Objects.equals(columns.get(i), primaryKeyName)) {
                values.remove(i);
                columns.remove(i);
            }
            if (Objects.isNull(values.get(i))) {
                values.remove(i);
                columns.remove(i);
            }
        }
        // 处理值
        StringBuilder stringBuffer = new StringBuilder();
        for (int i = 0; i < columns.size(); i++) {
            stringBuffer.append(columns.get(i)
                    .concat(SEPARATOR_EQUAL)
                    .concat(SEPARATOR_SINGLE_QUOTA)
                    .concat(Objects.nonNull(values.get(i)) ? String.valueOf(values.get(i)) : "null")
                    .concat(SEPARATOR_SINGLE_QUOTA)
                    .concat(SEPARATOR_COMMA)
            );
        }
        String bufferString = stringBuffer.toString();
        if (!bufferString.isEmpty()) {
            bufferString = bufferString.substring(0, stringBuffer.length() - 2);
        }
        // 组装 SQL
        String SQL = UPDATE_PREFIX
                .concat(getTableName(aClass))
                .concat(UPDATE_SET)
                .concat(bufferString)
                .concat(SEPARATOR_WHERE)
                .concat(primaryKeyName)
                .concat(SEPARATOR_EQUAL)
                .concat(SEPARATOR_SINGLE_QUOTA)
                .concat(String.valueOf(id))
                .concat(SEPARATOR_SINGLE_QUOTA);
        SQL = SQL.replaceAll("'null'", "null");
        TraceLog.out(SQL);
        ModelExecutor.execute(SQL);

        if (Holder.SPEED_ORM_CONFIG_INSTANCE.getOpenCache()) {
            // 清除相关缓存
            try {
                if (id != null) {
                    String tableName = getTableName(aClass);
                    cacheManager.evictById(tableName, id);

                    // 清理该类型的所有缓存
                    OffHeapManager.removeByEntityType(aClass);

                }
            } catch (Exception e) {
                log.error("Failed to clear cache", e);
            }
        }

    }

    public static <T> void deleteById(Object id, Class<?> tClass) {
        String key = getPrimaryKey(tClass);
        String SQL = DELETE_PREFIX
                .concat(getTableName(tClass)
                        .concat(SEPARATOR_WHERE)
                        .concat(key)
                        .concat(SEPARATOR_EQUAL)
                        .concat(SEPARATOR_SINGLE_QUOTA.concat(String.valueOf(id)).concat(SEPARATOR_SINGLE_QUOTA)));
        TraceLog.out(SQL);
        ModelExecutor.execute(SQL);

        if (Holder.SPEED_ORM_CONFIG_INSTANCE.getOpenCache()) {
            // 清除相关缓存
            try {
                if (id != null) {
                    String tableName = getTableName(tClass);
                    cacheManager.evictById(tableName, id);

                    // 清理该类型的所有缓存
                    OffHeapManager.removeByEntityType(tClass);

                }
            } catch (Exception e) {
                log.error("Failed to clear cache", e);
            }
        }

    }

    public static <T> void deleteLogicalById(Object id, Class<T> tClass) {
        String primaryKeyName = getPrimaryKey(tClass);
        String delFlagKey = ORMUtils.getLogicalDeleteField(tClass);
        String SQL = UPDATE_PREFIX
                .concat(getTableName(tClass))
                .concat(UPDATE_SET)
                .concat(delFlagKey)
                .concat(SEPARATOR_EQUAL)
                .concat("1")
                .concat(SEPARATOR_WHERE)
                .concat(primaryKeyName)
                .concat(SEPARATOR_EQUAL)
                .concat(SEPARATOR_SINGLE_QUOTA)
                .concat(String.valueOf(id))
                .concat(SEPARATOR_SINGLE_QUOTA);
        TraceLog.out(SQL);
        ModelExecutor.execute(SQL);

        if (Holder.SPEED_ORM_CONFIG_INSTANCE.getOpenCache()) {
            // 清除相关缓存
            try {
                if (id != null) {
                    String tableName = getTableName(tClass);
                    cacheManager.evictById(tableName, id);

                    // 清理该类型的所有缓存
                    OffHeapManager.removeByEntityType(tClass);

                }
            } catch (Exception e) {
                log.error("Failed to clear cache", e);
            }
        }

    }

    public static <T> void delete(Class<T> tClass) {
        String SQL = DELETE_PREFIX.concat(getTableName(tClass));
        TraceLog.out(SQL);
        ModelExecutor.execute(SQL);

        if (Holder.SPEED_ORM_CONFIG_INSTANCE.getOpenCache()) {
            // 清除相关缓存
            try {
                String tableName = getTableName(tClass);
                cacheManager.evictByTable(tableName);

                // 清理该类型的所有缓存
                OffHeapManager.removeByEntityType(tClass);

            } catch (Exception e) {
                log.error("Failed to clear cache", e);
            }
        }

    }

    public static <T> void delete(QueryOperator<T> queryOperator, Class<T> tClass) {
        List<QueryParams> paramsList = ORMUtils.getQueryParamsList(queryOperator, tClass);
        // 获取查询条件
        String mappingOperator = mappingOperator(paramsList).replaceFirst("AND", "WHERE");
        String SQL = DELETE_PREFIX.concat(getTableName(tClass)).concat(mappingOperator);
        TraceLog.out(SQL);
        ModelExecutor.execute(SQL);

        if (Holder.SPEED_ORM_CONFIG_INSTANCE.getOpenCache()) {
            // 清除相关缓存
            try {
                String tableName = getTableName(tClass);
                cacheManager.evictByTable(tableName);

                // 清理该类型的所有缓存
                OffHeapManager.removeByEntityType(tClass);

            } catch (Exception e) {
                log.error("Failed to clear cache", e);
            }
        }

    }

    public static <T> T selectById(Object id, Class<T> tClass) {
        // 先尝试从堆外缓存获取
        T offHeapResult = OffHeapManager.afterSelect(id, tClass);
        if (offHeapResult != null) {
            TraceLog.out("OffHeap cache HIT: " + id);
            return offHeapResult;
        }
        String key = getPrimaryKey(tClass);
        String SQL = SELECT_PREFIX.concat(getTableName(tClass)
                .concat(SEPARATOR_SPACE)
                .concat(SEPARATOR_WHERE)
                .concat(key)
                .concat(SEPARATOR_EQUAL)
                .concat(SEPARATOR_SINGLE_QUOTA.concat(String.valueOf(id)).concat(SEPARATOR_SINGLE_QUOTA)));
        TraceLog.out(SQL);
        return queryCacheable(SQL, tClass, () -> {
            T result = ModelExecutor.selectSingleResult(SQL, tClass);
            // 将结果存入堆外存储
            if (OffHeapManager.shouldStoreOffHeap(result)) {
                String offHeapKey = OffHeapManager.generateKey(id, tClass);
                OffHeapManager.put(offHeapKey, result);
                TraceLog.out("OffHeap cache POPULATED: " + offHeapKey);
            }
            return result;
        });
    }

    public static <T> void saveBatch(List<T> tList) {
        // 自动填充ID
        for (T entity : tList) {
            generateEntityId(entity);
        }
        List<String> stringList = Lists.newArrayList();
        for (T o : tList) {
            String INNER_SQL = buildBatchInsertSQL(o);
            stringList.add(INNER_SQL);
        }
        // 分片插入(每 1000 条执行一次批量插入)
        int batchSize = 1000;
        int total = stringList.size();
        // 需要执行的次数
        int insertTimes = total / batchSize;
        // 最后一次执行需要提交的记录数(防止可能不足 1000 条)
        int lastSize = batchSize;
        if (total % batchSize != 0) {
            insertTimes++;
            lastSize = total % batchSize;
        }
        for (int j = 0; j < insertTimes; j++) {
            if (insertTimes == j + 1) {
                batchSize = lastSize;
            }
            List<String> subList = stringList.subList(j * batchSize, (j * batchSize + batchSize));
            String saveBatchPrefix = "";
            List<String> valueList = Lists.newArrayList();
            for (String s : subList) {
                String[] split = s.split("VALUES");
                valueList.add(split[1]);
                saveBatchPrefix = split[0];
            }
            String SQL = saveBatchPrefix.concat(INSERT_VALUES).concat(String.join(",", valueList));
            TraceLog.out(SQL);
            // 分片执行批量插入
            ModelExecutor.execute(SQL);
        }

        if (Holder.SPEED_ORM_CONFIG_INSTANCE.getOpenCache()) {
            // 清除相关缓存
            try {
                Class<?> tClass = tList.get(0).getClass();
                String tableName = getTableName(tClass);
                cacheManager.evictByTable(tableName);

                // 清理该类型的所有缓存
                OffHeapManager.removeByEntityType(tClass);

            } catch (Exception e) {
                log.error("Failed to clear cache", e);
            }
        }

    }

    public static <T> PageResult<T> selectPage(Integer pageNum, Integer pageSize, QueryOperator<T> queryOperator, Class<T> tClass) {
        String SQL = SELECT_PREFIX
                .concat(getTableName(tClass))
                .concat(SEPARATOR_SPACE)
                .concat(mappingOperator(ORMUtils.getQueryParamsList(queryOperator, tClass)));
        SQL = SQL.replaceFirst("AND", "WHERE")
                .replace("WHERE  GROUP BY", "GROUP BY")
                .replace("WHERE  ORDER BY", "ORDER BY")
                .replace("AND  ORDER BY", "ORDER BY");
        BinaryOperator<Integer> multiply = (x, y) -> (x - 1) * y;
        SQL = SQL.concat(SEPARATOR_LIMIT)
                .concat(String.valueOf(multiply.apply(pageNum, pageSize)))
                .concat(SEPARATOR_COMMA)
                .concat(String.valueOf(pageSize));
        TraceLog.out(SQL);
        String finalSQL = SQL;
        return queryCacheable(SQL, (Class<PageResult<T>>) tClass, () -> ModelExecutor.selectPageResult(finalSQL, tClass));
    }

    public static <T> List<T> tTree(Class<T> tClass) {
        return (List<T>) TreeUtils.buildTree(Model.select(tClass));
    }

    // 缓存管理器实例
    private static final CacheManager cacheManager = createCacheManager();

    // 键锁映射（防止缓存击穿） - 在这里定义
    private static final ConcurrentMap<String, Lock> keyLocks = new ConcurrentHashMap<>();

    /**
     * 通用缓存查询方法（支持任意返回类型）
     *
     * @param sql        完整的SQL语句
     * @param resultType 返回类型（可为null）
     * @param dbLoader   数据库加载器
     * @return 查询结果（可能是任意类型）
     */
    private static <R> R queryCacheable(String sql, Class<R> resultType, Supplier<R> dbLoader) {
        SpeedOrmConfig speedOrmConfig = Holder.SPEED_ORM_CONFIG_INSTANCE;
        // 如果缓存功能未开启, 则直接执行数据库操作
        if (!speedOrmConfig.getOpenCache()) {
            return dbLoader.get();
        }
        // 1. 生成缓存键
        String cacheKey = CacheKeyGenerator.generateKey(sql, resultType);

        // 2. 尝试从缓存获取
        R result = cacheManager.get(cacheKey, resultType);
        if (result != null) {
            TraceLog.out("Cache HIT: " + cacheKey);
            return result;
        }

        // 3. 如果是void操作，直接执行不缓存
        if (resultType == Void.class) {
            TraceLog.out("Executing non-cacheable operation: " + sql);
            return dbLoader.get();
        }

        // 4. 获取键级锁（防止缓存击穿）
        Lock lock = keyLocks.computeIfAbsent(cacheKey, k -> new ReentrantLock());

        try {
            // 5. 加锁
            lock.lock();

            // 6. 双检锁：再次检查缓存
            result = cacheManager.get(cacheKey, resultType);
            if (result != null) {
                TraceLog.out("Cache HIT (under lock): " + cacheKey);
                return result;
            }

            // 7. 执行数据库操作
            TraceLog.out("Cache MISS - querying DB: " + cacheKey);
            result = dbLoader.get();

            // 8. 非空结果缓存
            if (result != null) {
                cacheManager.put(cacheKey, result, resultType);
                TraceLog.out("Cache POPULATED: " + cacheKey);
            }

            return result;
        } finally {
            // 9. 释放锁并从映射中移除
            lock.unlock();
            keyLocks.remove(cacheKey);
        }
    }

    // 创建缓存管理器实例
    private static CacheManager createCacheManager() {
        try {
            // 优先使用 Caffeine 高性能缓存库
            return new CaffeineCacheManager();
        } catch (Exception e) {
            // 回退到内置高性能缓存
            return new ConcurrentCacheManager();
        }
    }

    public static <T> void updateBatch(List<T> models) {
        for (List<?> partitionList : Lists.partition(models, 1000)) {
            BatchUpdateUtils.updateBatch(partitionList);
        }
    }

    public static <T> void deleteByIds(List<T> ids, Class<T> tClass) {
        SQLGenUtils.delete(new QueryOperator<T>().in(getPrimaryKey(tClass), ids), tClass);
    }

    public static <T> PageResult<T> selectCursorPage(
            Integer pageSize,
            String nextCursor,
            Boolean orderByDesc,
            QueryOperator<T> queryOperator,
            Class<T> tClass) {

        // 解析游标字段和排序方向
        String cursorField = getCursorField(tClass);
        Long cursorValue = parseCursorValue(nextCursor);

        // 构建基础SQL
        String baseSQL = buildBaseSQL(tClass, queryOperator);

        // 添加游标过滤条件
        String filteredSQL = addCursorCondition(baseSQL, cursorField, cursorValue, orderByDesc);

        // 添加LIMIT子句
        String finalSQL = addLimitClause(filteredSQL, pageSize);

        TraceLog.out("Cursor SQL: " + finalSQL);
        return queryCacheable(finalSQL, (Class<PageResult<T>>) tClass,
                () -> ModelExecutor.selectCursorPageResult(finalSQL, tClass));
    }

    private static <T> String buildBaseSQL(Class<T> tClass, QueryOperator<T> queryOperator) {
        String tableName = getTableName(tClass);
        String conditionPart = mappingOperator(ORMUtils.getQueryParamsList(queryOperator, tClass));

        String sql = SELECT_PREFIX + tableName + SEPARATOR_SPACE + conditionPart;

        return sql.replaceFirst("AND", "WHERE")
                .replace("WHERE  GROUP BY", "GROUP BY")
                .replace("WHERE  ORDER BY", "ORDER BY")
                .replace("AND  ORDER BY", "ORDER BY");
    }

    // 懒加载
    private static class Holder {
        static final SpeedOrmConfig SPEED_ORM_CONFIG_INSTANCE = SpringUtils.getBean(SpeedOrmConfig.class);
    }

}
